package interfaces.tables;

import java.util.List;

import fileHandling.language.Lang;
import fileHandling.language.interfaces.ScoreBoard;
import interfaces.superWidgets.ListenerKeeperElement;
import logic.common.player.Player;
import logic.common.player.playerListeners.PlayerValueListener;
import logic.common.team.Team;
import logic.common.team.teamListeners.DroneKillEvent;
import logic.common.team.teamListeners.TeamListener;
import logic.common.team.teamListeners.TeamValueChangedEvent;
import logic.status.StatusChangedEvent;

import networking.messages.syncMessages.ValueType;

import org.fenggui.util.Color;

public class TeamTable extends Table<TeamTableEntry> {
	
	private static final Lang[] TEAM_NAMES = 
		new Lang[] { ScoreBoard.Name, ScoreBoard.Kills, ScoreBoard.Deaths, ScoreBoard.Ping };
	private static final float[] TEAM_WIDTHS = new float[] { 0.4f, 0.2f, 0.2f, 0.2f };
	
	private PlayerMap<TeamTableEntry> playerEntries;
	private PlayerMap<PlayerValueListener> playerListeners;
	
	private Team team;
	private ListenerKeeperElement element;
	
	public TeamTable(int width, int height, int x, int y, Team team, ListenerKeeperElement element) {
		super(width, height, x, y, TEAM_NAMES, TEAM_WIDTHS);
		this.team = team;
		this.element = element;
		
		playerEntries = new PlayerMap<TeamTableEntry>();
		playerListeners = new PlayerMap<PlayerValueListener>();
		
		createTable();
		
		sortTable();
				
		layout();
		
		element.addListener(team, new TeamListener() {
			@Override
			public void playerAdded(Player player) {
				assert(!playerEntries.containsKey(player));
				addPlayerEntry(player);
				
				sortTable();
			}
			
			@Override
			public void playerRemoved(Player player) {
				assert(playerEntries.containsKey(player));
				removePlayerEntry(player);
				
				sortTable();
			}
			
			@Override
			public void teamValueChanged(TeamValueChangedEvent event) {}
			@Override
			public void droneDestroyed(DroneKillEvent event) {}
		});
	}
	
	private void createTable() {
		List<Player> players = team.getAllPlayers();
		for(int i = 0; i < players.size(); i++) {
			addPlayerEntry(players.get(i));
		}
	}
	
	private void addPlayerEntry(Player player) {
		PlayerValueListener l = new PlayerValueListener() {
			@Override
			public void valueChanged(StatusChangedEvent event) {
				ValueType type = event.getType();
				if(type == ValueType.Kills || type == ValueType.Deaths) sortTable();
			}
		};
		playerListeners.put(player, l);
		element.addListener(player, l);
		
		TeamTableEntry entry = new TeamTableEntry(entryWidth, labelHeight, 0, player, this);
		playerEntries.put(player, entry);
		addTableEntry(entry);
	}
	
	private void removePlayerEntry(Player player) {
		TeamTableEntry entry = playerEntries.remove(player);
		PlayerValueListener l = playerListeners.get(player);
		player.removePlayerValueListener(l);
		removeTableEntry(entry);
		sortTable();
	}
	
	private void sortTable() {
		int i = 1;
		List<Player> sortedPlayers = team.getSortedPlayers();
		for(Player player : sortedPlayers) {
			TeamTableEntry entry = playerEntries.get(player);
			if(entry != null) {
				entry.setY(tableContent.getHeight() - (i * labelHeight));
				i++;
			}
		}
		
		layout();
	}
	
	@Override
	protected int getBorder() { return getHeight() / 30; }
	
	@Override
	protected Color getHeaderTextColor() { return Color.BLACK; }
	
	@Override
	protected Color getHeaderBGColor() { return Color.LIGHT_BLUE; }
	
	@Override
	protected Color getTableBGColor() { return Color.LIGHT_GRAY; }
	
	@Override
	protected boolean showScrollBars() { return false; }
	
	@Override
	public boolean allowSelection() { return false; }
	
	public PlayerMap<TeamTableEntry> getPlayerMap() { return playerEntries; }
}